package com.danciyixue.boot.dcyx.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.danciyixue.boot.core.security.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.danciyixue.boot.dcyx.mapper.UnitStudyStatsMapper;
import com.danciyixue.boot.dcyx.service.UnitStudyStatsService;
import com.danciyixue.boot.dcyx.service.UserCurrentUnitsService;
import com.danciyixue.boot.dcyx.model.entity.UnitStudyStats;
import com.danciyixue.boot.dcyx.model.form.UnitStudyStatsForm;
import com.danciyixue.boot.dcyx.model.query.UnitStudyStatsQuery;
import com.danciyixue.boot.dcyx.model.vo.UnitStudyStatsVO;
import com.danciyixue.boot.dcyx.converter.UnitStudyStatsConverter;
import com.danciyixue.boot.common.util.BeanCopyUtils;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;

/**
 * 单元学习统计服务实现类
 *
 * @author youlaitech
 * @since 2025-06-15 16:32
 */
@Service
@DS("dcyx")
@RequiredArgsConstructor
public class UnitStudyStatsServiceImpl extends ServiceImpl<UnitStudyStatsMapper, UnitStudyStats> implements UnitStudyStatsService {

    private final UnitStudyStatsConverter unitStudyStatsConverter;
    private final UserCurrentUnitsService userCurrentUnitsService;

    /**
    * 获取单元学习统计分页列表
    *
    * @param queryParams 查询参数
    * @return {@link IPage<UnitStudyStatsVO>} 单元学习统计分页列表
    */
    @Override
    public IPage<UnitStudyStatsVO> getUnitStudyStatsPage(UnitStudyStatsQuery queryParams) {
        Page<UnitStudyStatsVO> pageVO = this.baseMapper.getUnitStudyStatsPage(
                new Page<>(queryParams.getPageNum(), queryParams.getPageSize()),
                queryParams
        );
        return pageVO;
    }
    
    /**
     * 获取单元学习统计表单数据
     *
     * @param id 单元学习统计ID
     * @return 单元学习统计表单数据
     */
    @Override
    public UnitStudyStatsForm getUnitStudyStatsFormData(Long id) {
        UnitStudyStats entity = this.getById(id);
        return unitStudyStatsConverter.toForm(entity);
    }
    
    /**
     * 新增单元学习统计
     *
     * @param formData 单元学习统计表单对象
     * @return 是否新增成功
     */
    @Override
    public boolean saveUnitStudyStats(UnitStudyStatsForm formData) {
        UnitStudyStats entity = unitStudyStatsConverter.toEntity(formData);
        return this.save(entity);
    }
    
    /**
     * 更新单元学习统计
     *
     * @param id   单元学习统计ID
     * @param formData 单元学习统计表单对象
     * @return 是否修改成功
     */
    @Override
    public boolean updateUnitStudyStats(Long id,UnitStudyStatsForm formData) {
        UnitStudyStats entity = unitStudyStatsConverter.toEntity(formData);
        return this.updateById(entity);
    }
    
    /**
     * 删除单元学习统计
     *
     * @param ids 单元学习统计ID，多个以英文逗号(,)分割
     * @return 是否删除成功
     */
    @Override
    public boolean deleteUnitStudyStatss(String ids) {
        Assert.isTrue(StrUtil.isNotBlank(ids), "删除的单元学习统计数据为空");
        // 逻辑删除
        List<Long> idList = Arrays.stream(ids.split(","))
                .map(Long::parseLong)
                .toList();
        return this.removeByIds(idList);
    }

    /**
     * 根据用户ID和单元ID更新单元学习统计
     * 如果记录不存在则插入新记录，如果存在则更新非空字段
     *
     * @param formData 单元学习统计表单对象
     * @return 是否操作成功
     */
    @Override
    public boolean saveOrUpdateUnitStudyStats(UnitStudyStatsForm formData) {
        // 参数校验
//        Assert.notNull(formData, "表单数据不能为空");
//        Assert.notNull(formData.getUserId(), "用户ID不能为空");
//        Assert.notNull(formData.getUnitId(), "单元ID不能为空");

        Long userId = SecurityUtils.getUserId();
        formData.setUserId(userId);
        // 根据用户ID和单元ID查找现有记录
        UnitStudyStats existingRecord = this.baseMapper.findByUserIdAndUnitId(
                userId, formData.getUnitId());

        boolean result;
        if (existingRecord == null) {
            // 记录不存在，插入新记录
            UnitStudyStats newEntity = unitStudyStatsConverter.toEntity(formData);
            result = this.save(newEntity);
        } else {
            // 记录存在，更新非空字段
            UnitStudyStats updateEntity = new UnitStudyStats();
            updateEntity.setId(existingRecord.getId());

            // 使用工具类复制非空字段
            copyNonNullProperties(formData, updateEntity);

            result = this.updateById(updateEntity);
        }

        // 如果单元学习统计更新成功，同步更新用户当前单元表
        if (result && formData.getUnitId() != null) {
            try {
                userCurrentUnitsService.updateCurrentUnitFromStats(userId, formData.getUnitId());
            } catch (Exception e) {
                // 记录日志但不影响主业务流程
                // 这里可以添加日志记录，但不抛出异常
            }
        }

        return result;
    }

    /**
     * 复制非空字段的工具方法
     * 只复制源对象中非空的字段到目标对象
     *
     * @param source 源对象
     * @param target 目标对象
     */
    private void copyNonNullProperties(UnitStudyStatsForm source, UnitStudyStats target) {
        BeanCopyUtils.copyIfNotNull(source::getUnitTotal, target::setUnitTotal);
        BeanCopyUtils.copyIfNotNull(source::getStudyNumZnjy, target::setStudyNumZnjy);
        BeanCopyUtils.copyIfNotNull(source::getStudyNumZnmx, target::setStudyNumZnmx);
        BeanCopyUtils.copyIfNotNull(source::getStudyNumZntx, target::setStudyNumZntx);
        BeanCopyUtils.copyIfNotNull(source::getTestTimeZnjy, target::setTestTimeZnjy);
        BeanCopyUtils.copyIfNotNull(source::getTestTimeZnmx, target::setTestTimeZnmx);
        BeanCopyUtils.copyIfNotNull(source::getTestTimeZntx, target::setTestTimeZntx);
        BeanCopyUtils.copyIfNotNull(source::getRestudyNumZnjy, target::setRestudyNumZnjy);
        BeanCopyUtils.copyIfNotNull(source::getRestudyNumZnmx, target::setRestudyNumZnmx);
        BeanCopyUtils.copyIfNotNull(source::getRestudyNumZntx, target::setRestudyNumZntx);
        BeanCopyUtils.copyIfNotNull(source::getIsEndZnjy, target::setIsEndZnjy);
        BeanCopyUtils.copyIfNotNull(source::getIsEndZnmx, target::setIsEndZnmx);
        BeanCopyUtils.copyIfNotNull(source::getIsEndZntx, target::setIsEndZntx);
    }

}
